package com.siruier.boss.ui.tool.image.select.service.impl

import android.content.Context
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.Observer
import com.alibaba.fastjson.JSON
import com.luck.picture.lib.PictureSelector
import com.luck.picture.lib.config.PictureConfig
import com.luck.picture.lib.config.PictureMimeType
import com.luck.picture.lib.entity.LocalMedia
import com.luck.picture.lib.listener.OnResultCallbackListener
import com.siruier.boss.api.core.ApiComplete
import com.siruier.boss.api.core.ApiError
import com.siruier.boss.api.core.ApiProcess
import com.siruier.boss.api.core.FirmException
import com.siruier.boss.ui.api.ApiObserver
import com.siruier.boss.ui.tool.image.select.domain.ImageSelectBean
import com.siruier.boss.ui.tool.image.select.service.IImageSelect
import com.siruier.boss.ui.tool.image.select.service.ImageSelectIntercept
import com.siruier.boss.ui.tool.image.select.service.ImageUploadUBuilder
import com.siruier.boss.ui.tool.image.select.service.intercept.ApiUploadFileIntercept
import com.siruier.boss.ui.utils.GlideEngine
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException

abstract class AbstractImageSelect : IImageSelect, DefaultLifecycleObserver {
    companion object {
        private val mImageSelectIntercepts: MutableList<ImageSelectIntercept> =
            mutableListOf(ApiUploadFileIntercept)
    }

    private lateinit var mBuilder: ImageUploadUBuilder

    abstract val context: Context?
    abstract val pictureSelector: PictureSelector
    abstract fun <T> launchUI(
        block: suspend CoroutineScope.() -> T,
        apiObserver: Observer<ApiProcess<T>>? = null,
        error: ApiError? = null,
        complete: ApiComplete? = null,
    )

    override fun selectImage(config: (ImageUploadUBuilder.() -> Unit)?) {
        mBuilder = config?.let { ImageUploadUBuilder().apply(it) } ?: ImageUploadUBuilder()
        launchUI({
            var result = openGallery()
            if (mImageSelectIntercepts.isNotEmpty()) {
                mImageSelectIntercepts.forEach {
                    result = it.intercept(mBuilder, result)
                }
            }
            result
        }, ApiObserver(context) { result ->
            mBuilder.onUploadSuccessListener?.invoke(result)
        }, error = {
            mBuilder.onCancelSuccessListener?.invoke()
        })
    }

    private suspend fun openGallery() =
        suspendCancellableCoroutine<MutableList<ImageSelectBean>?> { coroutine ->
            pictureSelector
                .openGallery(PictureMimeType.ofImage())
                .imageEngine(GlideEngine.createGlideEngine())
                .queryMimeTypeConditions("image/png", "image/jpeg", "image/jpg")
                .isWeChatStyle(true)
                .maxSelectNum(mBuilder.selectCount)
                .imageSpanCount(mBuilder.columnCount)
                .isCamera(true)
                .isPreviewImage(true)
                .selectionMode(if (mBuilder.isMultipleChoice) PictureConfig.MULTIPLE else PictureConfig.SINGLE)
                .forResult(object : OnResultCallbackListener<LocalMedia> {
                    override fun onResult(result: List<LocalMedia>?) {
                        coroutine.resume(result?.mapTo(mutableListOf()) {
                            JSON.toJavaObject(JSON.toJSON(it) as JSON?, ImageSelectBean::class.java)
                        })
                    }

                    override fun onCancel() {
                        coroutine.resumeWithException(FirmException(""))
                    }
                })
        }
}